

PM_FUNC_STOCK_ATTRIB get_distance_to_line( Vector:vStart[3], Vector:vEnd[3], Vector:vObject[3] )
{
	// Imagine a triagle, vStart to vEnd line is AC, vObject point is B
	//      B_
	//     /  |_
	//    /     |_
	//   A - - - - C

	//some variables for what we are going to store
	new Vector:vStartEnd[3], Vector:vStartObject[3];

	// vector from start to end, line CA
	xs_vec_sub( vEnd, vStart, vStartEnd );
	// vector from end to object, line BA
	xs_vec_sub( vObject, vStart, vStartObject );

	new Float:fStartObject = vector_length( vStartObject );
	new Float:fAngleStart = floatacos( xs_vec_dot( vStartEnd, vStartObject ) / ( vector_length( vStartEnd ) * fStartObject ), degrees );
	if( fAngleStart > 90.0 ) 
		return floatround( fStartObject );

	//some more variables for what we are going to store
	new Vector:vEndObject[3], Vector:vEndStart[3];
	// vector from end to start, line AC
	xs_vec_sub( vStart, vEnd, vEndStart );
	// vector object to end, line CB
	xs_vec_sub( vEnd, vObject, vEndObject );

	new Float:fEndObject = vector_length( vEndObject );
	new Float:fAngleEnd = floatacos( xs_vec_dot( vEndStart, vEndObject ) / ( vector_length( vEndStart ) * fEndObject ), degrees );
	if( fAngleEnd > 90.0 ) 
		return floatround( fEndObject );

	return floatround( fStartObject * floatsin( fAngleStart, degrees ) );
}

PM_FUNC_STOCK_ATTRIB bool:is_user_stuck( Int:id, Int:iHullsize = -1 )
{
	if ( iHullsize == -1 )
		iHullsize = PlayerHullSize( id );
	new Vector:vOrigin[3], Int:iTrace = 0; 
	pev( id, pev_origin, vOrigin );
	engfunc( EngFunc_TraceHull, vOrigin, vOrigin, DONT_IGNORE_MONSTERS, iHullsize, id, iTrace );
	if( get_tr2( iTrace, TR_StartSolid ) || get_tr2( iTrace, TR_AllSolid ) || !get_tr2( iTrace, TR_InOpen ) )
		return true;
	return false;
}

PM_FUNC_STOCK_ATTRIB UnStuck( Int:id, Int:iHullsize = -1, Int:iStartDist = 32, Int:iAddDist = 32, Int:iMaxDist = 1000, Int:iAttempts = 128 )
{
	if ( iHullsize == -1 )
		iHullsize = PlayerHullSize( id );

	if( iHullsize == -1 || !is_user_stuck( id, iHullsize ) ) 
	{
		return true;
	}

	new Vector:vOrigin[3], Vector:vNewOrigin[3], Int:i;
	pev( id, pev_origin, vOrigin );

	for ( new Int:iDistance = iStartDist; iDistance < iMaxDist; iDistance += iAddDist )
	{
		for( i = 0; i < iAttempts; i++ )
		{
			vNewOrigin[0] = random_float( vOrigin[0] - iDistance, vOrigin[0] + iDistance );
			vNewOrigin[1] = random_float( vOrigin[1] - iDistance, vOrigin[1] + iDistance );
			vNewOrigin[2] = random_float( vOrigin[2] - iDistance, vOrigin[2] + iDistance );

			if ( fm_trace_hull( vNewOrigin, iHullsize, id ) == 0 )
			{
				fm_entity_set_origin( id, vNewOrigin );
				return true;
			}
		}
	}

	return false;
}

PM_FUNC_STOCK_ATTRIB entity_follow_target( Int:iEntity, Int:iTarget, Float:fSpeed, bool:bSetAngles = true )
{
	if ( !pev_valid( iEntity ) || !pev_valid( iTarget ) )
		return 0;

	new Vector:vOrigin[3], Vector:vEntOrigin[3];
	pev( iTarget, pev_origin, vOrigin );
	pev( iEntity, pev_origin, vEntOrigin );

	new Float:fInvTime = ( fSpeed / vector_distance( vOrigin, vEntOrigin ) );

	new Vector:vVelocity[3];
	vVelocity[0] = ( vOrigin[0] - vEntOrigin[0] ) * fInvTime;
	vVelocity[1] = ( vOrigin[1] - vEntOrigin[1] ) * fInvTime;
	vVelocity[2] = ( vOrigin[2] - vEntOrigin[2] ) * fInvTime;

	set_pev( iEntity, pev_velocity, vVelocity );

	if ( bSetAngles )
	{
		new Vector:vNewAngle[3];
		vector_to_angle( vVelocity, vNewAngle );
		set_pev( iEntity, pev_angles, vNewAngle );
	}

	return 1;
}


PM_FUNC_STOCK_ATTRIB Vector:CoordToVector( Coord:cCoord[3], Vector:vVector[3] = {0.0,0.0,0.0} )
{
	IVecFVec( cCoord, vVector );
	return vVector;
}

PM_FUNC_STOCK_ATTRIB Coord:VectorToCoord( Vector:vVector[3], Coord:cCoord[3] = {0,0,0} )
{
	FVecIVec( vVector, cCoord );
	return cCoord;
}

PM_FUNC_STOCK_ATTRIB ReduceNumber( Int:iNumber )
{
	new Int:iReduced = 1;
	while ( iReduced * 10 < iNumber )
		iReduced *= 10;

	return iReduced;
}
 
PM_FUNC_STOCK_ATTRIB RandomVector( Vector:vVec[3], Float:fMagnitude )
{
	vVec[0] = random_float( -fMagnitude, fMagnitude );
	vVec[1] = random_float( -fMagnitude, fMagnitude );
	vVec[2] = floatsqroot( ( fMagnitude * fMagnitude ) - ( vVec[0] * vVec[0] ) - ( vVec[1] * vVec[1] ) );
}

